#ifndef GAMEKIT_COMMON_EVENTSOURCE_H
#define GAMEKIT_COMMON_EVENTSOURCE_H

#include "gamekit/common/Delegate.h"

namespace gamekit
{

template<typename S, typename E, E _event>
class EventArgs
{
public:
	EventArgs(S* source);
	
	S* source(void) const;
	E event(void) const;

private:
	S* m_source;
};

template<typename S, typename E>
class EventSource
{
public:
	EventSource();
	virtual ~EventSource();

	template<E _event> void addEventHandler(Delegate<void, EventArgs<S, E, _event> >);
	template<E _event> void addEventHandler(void (*handler)(const EventArgs<S, E, _event>&));
	template<E _event, typename T> void addEventHandler(void (T::*handler)(const EventArgs<S, E, _event>&), T*);
};

template<typename S, typename E, E _event>
EventArgs<S, E, _event>::EventArgs(S* source)
	: m_source(source)
{
}

template<typename S, typename E, E _event>
S* EventArgs<S, E, _event>::source(void) const
{
	return m_source;
}

template<typename S, typename E>
EventSource<S, E>::EventSource()
{
}

template<typename S, typename E>
EventSource<S, E>::~EventSource()
{
}

template<typename S, typename E>
template<E _event>
void EventSource<S, E>::addEventHandler(Delegate<void, EventArgs<S, E, _event> > handler)
{
}

template<typename S, typename E>
template<E _event>
void EventSource<S, E>::addEventHandler(void (*handler)(const EventArgs<S, E, _event>&))
{
	typedef EventArgs<S, E, _event> Args;
	addEventHandler<_event>(Delegate<void, Args>::From(handler));
}

template<typename S, typename E>
template<E _event, typename T> 
void EventSource<S, E>::addEventHandler(void (T::*handler)(const EventArgs<S, E, _event>&), T* t)
{
	typedef EventArgs<S, E, _event> _Args;
	typedef Delegate<void, _Args> _Delegate;

	_Delegate delegate = _Delegate::From(handler, t);
	addEventHandler<_event>(delegate);
}

}


#endif
